﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.IO;
using System.Security.Cryptography;

namespace Dtf.Core.Remoting
{
    public class RemotingClient
    {
        public RemotingClient(Machine machine) : this(machine.MachineName)
        {
        }

        public RemotingClient(string serverName)
        {
            if (!m_isClientInitialized)
            {
                ChannelServices.RegisterChannel(new TcpClientChannel(), false);
                
                m_server = Activator.CreateInstance(typeof(RemotingServer), null, new Object[] { new System.Runtime.Remoting.Activation
.UrlAttribute("tcp://" + serverName + ":10861")}) as RemotingServer;
                m_isClientInitialized = true;
            }

        }

        ~RemotingClient()
        {
            GC.SuppressFinalize(this);
            Console.WriteLine("~RemotingClient");
            m_server.EndSession();
            m_server = null;
         
        }

        [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Assert, Unrestricted = true)]
        public T CreateInstance<T>(params object[] args)
        {

            if (!typeof(T).IsSerializable && !typeof(T).IsMarshalByRef)
            {
                throw new NotSupportedException();
            }
            
            
            string curDir = System.IO.Directory.GetCurrentDirectory();// (asm.Location);

            string[] strfiles = Directory.GetFiles(curDir, "*", SearchOption.AllDirectories);
            MD5 md5 = MD5.Create();
            foreach (string strfile in strfiles)
            {
                string reletivePath = strfile.Substring(curDir.Length+1);
                byte[] fileData = File.ReadAllBytes(strfile);
                byte[] fileMD5 = md5.ComputeHash(fileData);
                if (!m_server.CompareFileMD5(reletivePath, fileMD5))    //check if file is not the same
                {
                    m_server.SyncFile(reletivePath, fileData);
                }
                
            }
            return m_server.CreateInstance<T>(args);

        }

        private static bool m_isClientInitialized = false;
        private RemotingServer m_server;
    }
}
